package Export_module

import (
	"dba_toolbox/Global"
	"fmt"
	"io"
	"math"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/chzyer/readline"
	"github.com/gookit/color"
)

var (
	// color
	Green     = color.Green.Render
	Red       = color.Red.Render
	Completed = color.S256(255, 27)
)

func Export() {
	dirPath, err := getCurrentFilePath()
	if err != nil {
		panic(err)
	}

	fmt.Println("欢迎使用DBA_TOOLBOX的数据导出CSV功能")

	rl, err := readline.New("请输入要导出的表_格式[库名.表名]_例:test.tb_test> ")
	if err != nil {
		panic(err)
	}
	defer rl.Close()

	table_name, err := rl.Readline()

	if err != nil {
		panic(err)
	}

	defaultInput := "yes"
	r2, err := readline.New("导出CSV文件是否合并 yes or no [default yes]> ")
	if err != nil {
		panic(err)
	}
	defer rl.Close()

	input, err := r2.Readline()
	if err != nil {
		panic(err)
	}

	input = strings.TrimSpace(input)

	start_Time := time.Now()

	var count int
	query := fmt.Sprintf("SELECT COUNT(*) FROM %s", table_name)
	err = Global.DB.QueryRow(query).Scan(&count)
	if err != nil {
		panic(err.Error())
	}
	if input == "" {
		input = defaultInput
	}

	if strings.EqualFold(input, "no") {
		//切成4线程
		steps := int(math.Ceil(float64(count) / float64(4)))
		for i := 0; i < 4; i++ {
			fileName := fmt.Sprintf("%s/%s-%d.csv", dirPath, table_name, i)
			sharding := steps * i
			go CV_EXPORTS(sharding, steps, table_name, fileName)
			time.Sleep(time.Second)
		}
	} else {
		//切成6线程
		steps := int(math.Ceil(float64(count) / float64(6)))
		var wg sync.WaitGroup // 声明一个WaitGroup
		for i := 0; i < 6; i++ {
			fileName := fmt.Sprintf("%s/%d.csv", dirPath, i)
			sharding := steps * i
			wg.Add(1) // 为每个协程增加计数
			go func(start, step int, table, fileName string) {
				defer wg.Done() // 在协程结束时减少计数
				CV_EXPORTS(start, step, table, fileName)
			}(sharding, steps, table_name, fileName)
		}

		wg.Wait() // 等待所有协程完成
		mergeCSV(table_name)
	}

	color.BgGreen.Println("导出表成功:", table_name)

	//获取结束时间
	end_Time := time.Now()
	//计算两时间相差
	elapsed_time := end_Time.Sub(start_Time)
	//输出总耗时
	fmt.Println("导出总耗时：", elapsed_time)
}

func CV_EXPORTS(start int, steps int, table string, filename string) {

	query := fmt.Sprintf("select * into outfile '%s' from %s Limit %d , %d;", filename, table, start, steps)
	// fmt.Println(query)
	counts, err := Global.DB.Query(query)
	if err != nil {
		fmt.Printf("单表导出失败err:%v\n", err)
	}
	defer counts.Close()

}

func getCurrentFilePath() (string, error) {
	dirPath, err := os.Getwd()
	if err != nil {
		fmt.Println("无法获取当前工作目录：", err)
	}
	// winwos测试用
	// dirPath = "D:/mycode/gitee/dba_toolbox"
	return dirPath, nil
}

func mergeCSV(table_name string) {
	files := []string{"1.csv", "2.csv", "3.csv", "4.csv", "5.csv"}

	// 打开0.csv用于追加
	outputFile, err := os.OpenFile("0.csv", os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		panic(err)
	}
	defer outputFile.Close()

	// 依次打开1.csv、2.csv、3.csv，并将它们的内容追加到0.csv中
	for _, file := range files {
		inputFile, err := os.Open(file)
		if err != nil {
			panic(err)
		}
		defer inputFile.Close()

		_, err = io.Copy(outputFile, inputFile)
		if err != nil {
			panic(err)
		}
	}

	// 重命名0.csv为table_name.csv
	if err := os.Rename("0.csv", table_name+".csv"); err != nil {
		panic(err)
	}

	// 删除1.csv、2.csv、3.csv
	for _, file := range files {
		if err := os.Remove(file); err != nil {
			panic(err)
		}
	}
}
